package org.dingfugui.triple.link;

import org.dingfugui.triple.connection.Connection;
import org.dingfugui.triple.connection.ConnectionFactory;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author fugui.ding at 2015/6/12
 */
public class SimplePoolDirectLink extends DirectLink {

    private List<Connection> connectionList = new ArrayList<>();
    private Queue<Connection> queue = new LinkedBlockingQueue<>();
    private int size = 10;

    public SimplePoolDirectLink(String host, ConnectionFactory factory) {
        super(host, factory);
    }

    public SimplePoolDirectLink(String host, int port, ConnectionFactory factory) {
        super(host, port, factory);
    }

    public SimplePoolDirectLink(InetSocketAddress address, ConnectionFactory factory) {
        super(address, factory);
    }

    @Override
    public Connection getConnection() {
        if (queue.size() > 0) {//如果有连接
            return queue.poll();
        } else {
            if (connectionList.size() >= size) {//如果连接池已满
                resize();//清除废连接
                if (connectionList.size() >= size) {
                    return queue.poll();//如果依然不够，等待连接回收
                } else {//清理掉废连接，创建新连接
                    Connection newCon = createNewConnection();
                    connectionList.add(newCon);
                    return newCon;
                }
            } else {//如果连接池未满，创建新连接
                Connection newCon = createNewConnection();
                connectionList.add(newCon);
                return newCon;
            }
        }
    }

    private void resize() {
        Iterator<Connection> iterator = connectionList.iterator();

        while (iterator.hasNext()) {
            Connection con = iterator.next();
            if (con == null) {
                iterator.remove();
                continue;
            }
            if (con.isClose()) {
                iterator.remove();
                continue;
            }
        }
    }

    @Override
    public void destory(Connection con) {
        if (con != null) {
            if (con.isClose()) {
                connectionList.remove(con);
            } else {
                queue.add(con);
            }
        }
    }

    @Override
    public void close() {
        for (Connection con : connectionList) {
            if (con != null && !con.isClose()) {
                con.close();
            }
        }
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }
}
